﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JXT.PrimaryKey.Batman.Collections
{
    /// <summary>
    /// 已缓存对象List
    /// </summary>
    /// <typeparam name="T">缓存对象类型</typeparam>
    public class CachedList<T> : IList<T>
    {
        private static List<T> _cache;
        private static DateTime _cacheCreateTime;
        private static TimeSpan _cacheExpire;
        private static readonly object _synLock = new object();

        /// <summary>
        /// 初始化缓存
        /// </summary>
        /// <param name="fun">初始化list方法</param>
        /// <param name="ts">过期时间</param>
        private static void initCache(Func<IEnumerable<T>> fun, TimeSpan ts)
        {
            if (_cache == null)
            {
                lock (_synLock)
                {
                    if (_cache == null)
                    {
                        _cache = new List<T>(fun());
                        _cacheCreateTime = DateTime.Now;
                        _cacheExpire = ts;
                    }
                }
            }
            else
            {
                if (DateTime.Now - _cacheCreateTime > _cacheExpire)
                {
                    lock (_synLock)
                    {
                        _cache = new List<T>(fun());
                        _cacheCreateTime = DateTime.Now;
                        _cacheExpire = ts;
                    }
                }
            }
        }

        private Func<IEnumerable<T>> _creater;
        private TimeSpan _expire;

        protected List<T> InnerList
        {
            get
            {
                if (_cache == null)
                    initCache(_creater, _expire);
                return _cache;
            }
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="creater">创建器</param>
        public CachedList(Func<IEnumerable<T>> creater)
            : this(creater, TimeSpan.FromMinutes(15))
        {
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="creater">创建器</param>
        /// <param name="ts">过期时间</param>
        public CachedList(Func<IEnumerable<T>> creater, TimeSpan ts)
        {
            _creater = creater;
            _expire = ts;
            initCache(_creater, ts);
        }

        public int IndexOf(T item)
        {
            return InnerList.IndexOf(item);
        }

        public void Insert(int index, T item)
        {
            InnerList.Insert(index, item);
        }

        public void RemoveAt(int index)
        {
            InnerList.RemoveAt(index);
        }

        public T this[int index]
        {
            get
            {
                return InnerList[index];
            }
            set
            {
                InnerList[index] = value;
            }
        }

        public void Add(T item)
        {
            InnerList.Add(item);
        }

        public void Clear()
        {
            InnerList.Clear();
        }

        public bool Contains(T item)
        {
            return InnerList.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            InnerList.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return InnerList.Count; }
        }

        public bool IsReadOnly
        {
            get { return true; }
        }

        public bool Remove(T item)
        {
            return InnerList.Remove(item);
        }

        public IEnumerator<T> GetEnumerator()
        {
            return InnerList.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}
